package com.hefan.activity.service;

import com.alibaba.fastjson.JSON;
import com.cat.common.constant.RedisKeyConstant;
import com.cat.common.entity.ResultBean;
import com.cat.common.meta.ResultCode;
import com.cat.tiger.service.JedisService;
import com.hefan.activity.bean.HfActivityAttend;
import com.hefan.activity.bean.HfActivityCfgAttr;
import com.hefan.activity.bean.HfActivityCfgInfo;
import com.hefan.activity.dao.HfActivityAttendDao;
import com.hefan.activity.dao.HfActivityCfgAttrDao;
import com.hefan.activity.dao.HfActivityCfgInfoDao;
import com.hefan.activity.itf.HfActivityService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by lxw on 2016/11/17.
 */
@Component("hfActivityService")
public class HfActivityServiceImpl implements HfActivityService {

    private Logger logger = LoggerFactory.getLogger(HfActivityServiceImpl.class);

    @Resource
    private HfActivityCfgInfoDao hfActivityCfgInfoDao;

    @Resource
    private HfActivityAttendDao hfActivityAttendDao;

    @Resource
    private HfActivityCfgAttrDao hfActivityCfgAttrDao;

    @Resource
    private JedisService jedisService;

    @Override
    public HfActivityCfgInfo findHfActivityCfgInfo(long activityId) {
        //缓存中获取活动配置信息
        HfActivityCfgInfo hfActivityCfgInfo = findHfActivityCfgFromCatch(activityId);
        if(hfActivityCfgInfo != null) {
            return hfActivityCfgInfo;
        }
        //由数据库中获取活动配置信息
        hfActivityCfgInfo = findHfActivityCfgFromDb(activityId);
        if(hfActivityCfgInfo != null) {
            //向缓存中保存活动配置信息
            setHfActivityCfgInCatch(hfActivityCfgInfo);
        }
        return hfActivityCfgInfo;
    }

    @Override
    @Transactional(readOnly = true)
    public int findActivityAttendNum(long activityId, String userId) {
        return hfActivityAttendDao.getActivityAttendCount(activityId,userId);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public int saveActivityAttend(HfActivityAttend hfActivityAttend) {
        return hfActivityAttendDao.saveActivityAttendInfo(hfActivityAttend);
    }

    @Override
    @Transactional(readOnly = true)
    public List<HfActivityAttend> findActivityAttendHis(long activityId, int rowNum) {
        return hfActivityAttendDao.findActivityAttendHis(activityId,rowNum);
    }

    @Override
    @Transactional(readOnly = true)
    public List<HfActivityCfgAttr> findAvlidActivitCfgAttrList(long activityId) {
        List<HfActivityCfgAttr> newAttrList = new ArrayList<HfActivityCfgAttr>();
        List<HfActivityCfgAttr> attrList = findActivityAttrList(activityId);
        if(attrList == null || attrList.isEmpty()) {
          return null;
        }
        for (HfActivityCfgAttr hfActivityCfgAttr: attrList) {
            if(hfActivityCfgAttr.getAttrAvlidVal() > 0) {
                Long validNum = this.getActivitAttrIsUseNum(activityId,hfActivityCfgAttr.getId());
                if(validNum != null && validNum>0) {
                    hfActivityCfgAttr.setAttrAvlidVal(validNum);
                    newAttrList.add(hfActivityCfgAttr);
                }
            }
        }
        return newAttrList;
    }

    @Override
    @Transactional(readOnly = true)
    public List<HfActivityCfgAttr> findActivityAttrList(long activityId) {
        List<HfActivityCfgAttr> resList = findHfActivityCfgAttrFromCach(activityId);
        if(resList == null) {
            resList = findHfActivityCfgAttrFromDb(activityId);
            if(resList != null) {
                setHfActivityCfgAttrInCatch(activityId,resList);
            }
        }
        return resList;
    }

    @Override
    @Transactional(readOnly = true)
    public Long getActivitAttrIsUseNum(long activityId,long attrId) {
        try {
            String key = String.format(RedisKeyConstant.HF_ACTIVITY_ATTR_AVLID_NUM_KEY, activityId,attrId);
            if(jedisService.isExist(key)) {
                return jedisService.incrBy2(key,0);
            } else  {
                Long validNum = hfActivityCfgAttrDao.findHfActivityCfgAttrAvlidNum(activityId,attrId);
                jedisService.incrBy2(key,validNum);
                return validNum;
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("hfActivityService----getActivitAttrIsUseNum---exception:"+e.getMessage());
        }
        return null;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public int incrActivityCfgAttrAvlidNum(long activityId, long attrId, long avlidNum) {
        Long cachValidNum = this.incrHfActivitAttrAvlidNumFromCach(activityId,attrId,avlidNum);
        int rowNum = 1;
        if(cachValidNum == null) {
            //累计更新
            rowNum = hfActivityCfgAttrDao.updateHfActivityCfgAttrAvlidNum(1,activityId,attrId,avlidNum);
        } else if(cachValidNum >= 0) {
            //全量更新
           hfActivityCfgAttrDao.updateHfActivityCfgAttrAvlidNum(2,activityId,attrId,cachValidNum);
        }  else {
            rowNum = 0;
        }
        return rowNum;
    }


    /**
     * 缓存中获取活动配置信息
     * @param activityId
     * @return
     */
    private HfActivityCfgInfo findHfActivityCfgFromCatch(long activityId) {
        String key = String.format(RedisKeyConstant.HF_ACTIVITY_CFG_KEY,activityId);
        try {
            String resStr = jedisService.getStr(key);
            if(StringUtils.isNotBlank(resStr)) {
                HfActivityCfgInfo hfActivityCfgInfo = JSON.parseObject(resStr,HfActivityCfgInfo.class);
                return hfActivityCfgInfo;
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("hfActivityService----findHfActivityCfgFromCatch---exception:"+e.getMessage());
        }
        return null;
    }

    /**
     * 由数据库中获取活动配置信息
     * @param activityId
     * @return
     */
    private  HfActivityCfgInfo findHfActivityCfgFromDb(long activityId) {
        return hfActivityCfgInfoDao.findActivityById(activityId);
    }

    /**
     * 向缓存中保存活动配置信息
     * @param hfActivityCfgInfo
     */
    private void setHfActivityCfgInCatch(HfActivityCfgInfo hfActivityCfgInfo) {
        String key = String.format(RedisKeyConstant.HF_ACTIVITY_CFG_KEY,hfActivityCfgInfo.getId());
        try {
            String resStr = jedisService.setexStr(key, JSON.toJSONString(hfActivityCfgInfo), RedisKeyConstant.HF_ACTIVITY_CFG__SECONDS);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("hfActivityService----setHfActivityCfgInCatch---exception:"+e.getMessage());
        }
    }


    /**
     * 由缓存中获取活动attr属性列表
     * @param activityId
     * @return
     */
    private List<HfActivityCfgAttr> findHfActivityCfgAttrFromCach(long activityId) {
        String key = String.format(RedisKeyConstant.HF_ACTIVITY_ATTR_KEY,activityId);
        try {
            String resStr = jedisService.getStr(key);
            if(StringUtils.isNotBlank(resStr)) {
                List<HfActivityCfgAttr> attrList = JSON.parseArray(resStr,HfActivityCfgAttr.class);
                return attrList;
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("hfActivityService----findHfActivityCfgAttrFromCach---exception:"+e.getMessage());
        }
        return null;
    }

    /**
     * 由DB中获取活动attr属性列表
     * @param activityId
     * @return
     */
    private List<HfActivityCfgAttr> findHfActivityCfgAttrFromDb(long activityId) {
        return hfActivityCfgAttrDao.findHfActivityCfgAttrList(activityId);
    }

    /**
     * 向缓存中保存活动属性信息
     * @param activityId
     * @param resList
     */
    private void setHfActivityCfgAttrInCatch(long activityId,List<HfActivityCfgAttr> resList) {
        String key = String.format(RedisKeyConstant.HF_ACTIVITY_ATTR_KEY,activityId);
        try {
            String resStr = jedisService.setexStr(key, JSON.toJSONString(resList), RedisKeyConstant.HF_ACTIVITY_ATTR_SECONDS);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("hfActivityService----setHfActivityCfgAttrInCatch---exception:"+e.getMessage());
        }
    }

    /**
     * 缓存中活动属性可用值进行消费
     * @param activityId
     * @param attrId
     * @return
     */
    private Long incrHfActivitAttrAvlidNumFromCach(long activityId,long attrId, long val) {
        try {
            String key = String.format(RedisKeyConstant.HF_ACTIVITY_ATTR_AVLID_NUM_KEY, activityId,attrId);
            if(jedisService.isExist(key)) {
                Long avlidNum = jedisService.incrBy2(key,val);
                if(avlidNum == null) {
                    return null;
                } else if(avlidNum < 0) {
                    jedisService.del(key);
                    return -1L;
                }
                return avlidNum;
            } else  {
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("hfActivityService----incrHfActivitCfgAttrAvlidNum---exception:"+e.getMessage());
        }
        return null;
    }

}
